#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
+static unsigned long virt_startinfo_addr;
+static unsigned long startinfo_frame;
+
static char *argv0 = "internal_domain_build";
static long get_tot_pages(int domain_id)
num_pgt_updates++;
}
- builddomain->virt_startinfo_addr =
+ virt_startinfo_addr =
virt_load_addr + ((alloc_index-1) << PAGE_SHIFT);
+ startinfo_frame = page_array[alloc_index-1];
- start_info = map_pfn(page_array[alloc_index-1]);
+ start_info = map_pfn(startinfo_frame);
memset(start_info, 0, sizeof(*start_info));
start_info->pt_base = virt_load_addr + ((tot_pages-1) << PAGE_SHIFT);
start_info->mod_start = initrd_addr;
ctxt->i386_ctxt.ss = FLAT_RING1_DS;
ctxt->i386_ctxt.cs = FLAT_RING1_CS;
ctxt->i386_ctxt.eip = load_addr;
- ctxt->i386_ctxt.esp = launch_op.u.builddomain.virt_startinfo_addr;
- ctxt->i386_ctxt.esi = launch_op.u.builddomain.virt_startinfo_addr;
+ ctxt->i386_ctxt.esp = virt_startinfo_addr;
+ ctxt->i386_ctxt.esi = virt_startinfo_addr;
ctxt->i386_ctxt.eflags = (1<<9) | (1<<2);
/* FPU is set up to default initial state. */
/* Ring 1 stack is the initial stack. */
ctxt->ring1_ss = FLAT_RING1_DS;
- ctxt->ring1_esp = launch_op.u.builddomain.virt_startinfo_addr;
+ ctxt->ring1_esp = virt_startinfo_addr;
/* No debugging. */
memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
ctxt->failsafe_callback_cs = FLAT_RING1_CS;
ctxt->failsafe_callback_eip = 0;
+ ctxt->start_info_frame = startinfo_frame;
+
launch_op.u.builddomain.domain = domain_id;
launch_op.u.builddomain.num_vifs = atoi(argv[3]);
p->failsafe_selector;
op.u.getdomaininfo.ctxt.failsafe_callback_eip =
p->failsafe_address;
+ op.u.getdomaininfo.ctxt.start_info_frame =
+ p->thread.start_info_frame;
}
}
read_unlock_irqrestore(&tasklist_lock, flags);
*/
int final_setup_guestos(struct task_struct *p, dom0_builddomain_t *builddomain)
{
- start_info_t *virt_startinfo_addr;
+ start_info_t *startinfo;
unsigned long phys_l2tab;
net_ring_t *shared_rings;
net_vif_t *net_vif;
p->event_address = builddomain->ctxt.event_callback_eip;
p->failsafe_selector = builddomain->ctxt.failsafe_callback_cs;
p->failsafe_address = builddomain->ctxt.failsafe_callback_eip;
+ p->thread.start_info_frame = builddomain->ctxt.start_info_frame;
/* NB. Page base must already be pinned! */
phys_l2tab = builddomain->ctxt.pt_base;
/* Set up the shared info structure. */
update_dom_time(p->shared_info);
- virt_startinfo_addr = (start_info_t *)builddomain->virt_startinfo_addr;
-
- /*
- * We need to populate start_info struct within the context of the new
- * domain. Thus temporarely install its pagetables.
- */
- __cli();
- __asm__ __volatile__ (
- "mov %%eax,%%cr3" : : "a" (pagetable_val(p->mm.pagetable)));
+ startinfo = (start_info_t *)
+ map_domain_mem(p->thread.start_info_frame << PAGE_SHIFT);
/* Add virtual network interfaces and point to them in startinfo. */
- while (builddomain->num_vifs-- > 0) {
+ while ( builddomain->num_vifs-- > 0 )
+ {
net_vif = create_net_vif(p->domain);
shared_rings = net_vif->shared_rings;
if (!shared_rings) panic("no network ring!\n");
for ( i = 0; i < MAX_DOMAIN_VIFS; i++ )
{
if ( p->net_vif_list[i] == NULL ) continue;
- virt_startinfo_addr->net_rings[i] =
+ startinfo->net_rings[i] =
virt_to_phys(p->net_vif_list[i]->shared_rings);
- memcpy(virt_startinfo_addr->net_vmac[i],
+ memcpy(startinfo->net_vmac[i],
p->net_vif_list[i]->vmac, ETH_ALEN);
}
/* Add block io interface */
- virt_startinfo_addr->blk_ring = virt_to_phys(p->blk_ring_base);
+ startinfo->blk_ring = virt_to_phys(p->blk_ring_base);
- /* Reinstate the caller's page tables. */
- __asm__ __volatile__ (
- "mov %%eax,%%cr3" : : "a" (pagetable_val(current->mm.pagetable)));
- __sti();
+ unmap_domain_mem(startinfo);
p->flags |= PF_CONSTRUCTED;
update_dom_time(p->shared_info);
p->shared_info->domain_time = 0;
+ /* DOM0 can't be stopped/started, so no need for an ongoing s.i. frame. */
+ p->thread.start_info_frame = 0;
+
virt_startinfo_address = (start_info_t *)
(virt_load_address + ((alloc_index - 1) << PAGE_SHIFT));
virt_stack_address = (unsigned long)virt_startinfo_address;
};
struct thread_struct {
+ unsigned long start_info_frame; /* Filled in on DOM0_START */
unsigned long esp1, ss1;
/* Hardware debugging registers */
unsigned long debugreg[8]; /* %%db0-7 debug registers */
long set_fast_trap(struct task_struct *p, int idx);
#define INIT_THREAD { \
- 0, 0, \
+ 0, 0, 0, \
{ [0 ... 7] = 0 }, /* debugging registers */ \
{ { 0, }, }, /* 387 state */ \
0x20, { 0, 0 }, /* DEFAULT_FAST_TRAP */ \
unsigned long event_callback_eip;
unsigned long failsafe_callback_cs; /* CS:EIP of failsafe callback */
unsigned long failsafe_callback_eip;
+ unsigned long start_info_frame; /* Page frame containing s.i. */
} full_execution_context_t;
#define MAX_CMD_LEN 256
{
/* IN variables. */
unsigned int domain;
- unsigned long virt_startinfo_addr;
unsigned int num_vifs;
full_execution_context_t ctxt;
} dom0_builddomain_t;
goto fail;
}
- err = request_irq(_EVENT_DEBUG, dbg_network_int, SA_SHIRQ, "debug", NULL);
+ err = request_irq(_EVENT_DEBUG, dbg_network_int, 0, "debug", NULL);
if ( err )
printk(KERN_WARNING "Non-fatal error -- no debug interrupt\n");